home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / gfx / show / mpeg2decodeWOS.lha / mpeg2decode / src / store.c < prev    next >
C/C++ Source or Header  |  1999-02-23  |  16KB  |  617 lines

  1. /* store.c, picture output routines                                         */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5. /*
  6.  * Disclaimer of Warranty
  7.  *
  8.  * These software programs are available to the user without any license fee or
  9.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  10.  * any and all warranties, whether express, implied, or statuary, including any
  11.  * implied warranties or merchantability or of fitness for a particular
  12.  * purpose.  In no event shall the copyright-holder be liable for any
  13.  * incidental, punitive, or consequential damages of any kind whatsoever
  14.  * arising from the use of these programs.
  15.  *
  16.  * This disclaimer of warranty extends to the user of these programs and user's
  17.  * customers, employees, agents, transferees, successors, and assigns.
  18.  *
  19.  * The MPEG Software Simulation Group does not represent or warrant that the
  20.  * programs furnished hereunder are free of infringement of any third-party
  21.  * patents.
  22.  *
  23.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  24.  * are subject to royalty fees to patent holders.  Many of these patents are
  25.  * general enough such that they are unavoidable regardless of implementation
  26.  * design.
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <fcntl.h>
  33.  
  34. #include "config.h"
  35. #include "global.h"
  36.  
  37. /* private prototypes */
  38. static void store_one _ANSI_ARGS_((char *outname, unsigned char *src[],
  39.   int offset, int incr, int height));
  40. static void store_yuv _ANSI_ARGS_((char *outname, unsigned char *src[],
  41.   int offset, int incr, int height));
  42. static void store_sif _ANSI_ARGS_((char *outname, unsigned char *src[],
  43.   int offset, int incr, int height));
  44. static void store_ppm_tga _ANSI_ARGS_((char *outname, unsigned char *src[],
  45.   int offset, int incr, int height, int tgaflag));
  46. static void store_yuv1 _ANSI_ARGS_((char *name, unsigned char *src,
  47.   int offset, int incr, int width, int height));
  48. static void putbyte _ANSI_ARGS_((int c));
  49. static void putword _ANSI_ARGS_((int w));
  50. static void conv422to444 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  51. static void conv420to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  52.  
  53. #define OBFRSIZE 4096
  54. static unsigned char obfr[OBFRSIZE];
  55. static unsigned char *optr;
  56. static int outfile;
  57.  
  58. /*
  59.  * store a picture as either one frame or two fields
  60.  */
  61. #ifdef STORM
  62. void Write_Frame(unsigned char *src[],int frame)
  63. #else
  64. void Write_Frame(src,frame)
  65. unsigned char *src[];
  66. int frame;
  67. #endif
  68. {
  69.   char outname[FILENAME_LENGTH];
  70.  
  71.   if (progressive_sequence || progressive_frame || Frame_Store_Flag)
  72.   {
  73.     /* progressive */
  74.     sprintf(outname,Output_Picture_Filename,frame,'f');
  75.     store_one(outname,src,0,Coded_Picture_Width,vertical_size);
  76.   }
  77.   else
  78.   {
  79.     /* interlaced */
  80.     sprintf(outname,Output_Picture_Filename,frame,'a');
  81.     store_one(outname,src,0,Coded_Picture_Width<<1,vertical_size>>1);
  82.  
  83.     sprintf(outname,Output_Picture_Filename,frame,'b');
  84.     store_one(outname,src,
  85.       Coded_Picture_Width,Coded_Picture_Width<<1,vertical_size>>1);
  86.   }
  87. }
  88.  
  89. /*
  90.  * store one frame or one field
  91.  */
  92. #ifdef STORM
  93. static void store_one(char *outname,unsigned char *src[],int offset,int incr,int height)
  94. #else
  95. static void store_one(outname,src,offset,incr,height)
  96. char *outname;
  97. unsigned char *src[];
  98. int offset, incr, height;
  99. #endif
  100. {
  101.   switch (Output_Type)
  102.   {
  103.   case T_YUV:
  104.     store_yuv(outname,src,offset,incr,height);
  105.     break;
  106.   case T_SIF:
  107.     store_sif(outname,src,offset,incr,height);
  108.     break;
  109.   case T_TGA:
  110.     store_ppm_tga(outname,src,offset,incr,height,1);
  111.     break;
  112.   case T_PPM:
  113.     store_ppm_tga(outname,src,offset,incr,height,0);
  114.     break;
  115. #ifdef DISPLAY
  116.   case T_X11:
  117.     dither(src);
  118.     break;
  119. #endif
  120.   default:
  121.     break;
  122.   }
  123. }
  124.  
  125. /* separate headerless files for y, u and v */
  126. #ifdef STORM
  127. static void store_yuv(char *outname,unsigned char *src[],int offset,int incr,int height)
  128. #else
  129. static void store_yuv(outname,src,offset,incr,height)
  130. char *outname;
  131. unsigned char *src[];
  132. int offset,incr,height;
  133. #endif
  134. {
  135.   int hsize;
  136.   char tmpname[FILENAME_LENGTH];
  137.  
  138.   hsize = horizontal_size;
  139.  
  140.   sprintf(tmpname,"%s.Y",outname);
  141.   store_yuv1(tmpname,src[0],offset,incr,hsize,height);
  142.  
  143.   if (chroma_format!=CHROMA444)
  144.   {
  145.     offset>>=1; incr>>=1; hsize>>=1;
  146.   }
  147.  
  148.   if (chroma_format==CHROMA420)
  149.   {
  150.     height>>=1;
  151.   }
  152.  
  153.   sprintf(tmpname,"%s.U",outname);
  154.   store_yuv1(tmpname,src[1],offset,incr,hsize,height);
  155.  
  156.   sprintf(tmpname,"%s.V",outname);
  157.   store_yuv1(tmpname,src[2],offset,incr,hsize,height);
  158. }
  159.  
  160. /* auxiliary routine */
  161. #ifdef STORM
  162. static void store_yuv1(char *name,unsigned char *src,int offset,int incr,int width,int height)
  163. #else
  164. static void store_yuv1(name,src,offset,incr,width,height)
  165. char *name;
  166. unsigned char *src;
  167. int offset,incr,width,height;
  168. #endif
  169. {
  170.   int i, j;
  171.   unsigned char *p;
  172.  
  173.   if (!Quiet_Flag)
  174.     fprintf(stderr,"saving %s\n",name);
  175.  
  176.   if ((outfile = open(name,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  177.   {
  178.     sprintf(Error_Text,"Couldn't create %s\n",name);
  179.     Error(Error_Text);
  180.   }
  181.  
  182.   optr=obfr;
  183.  
  184.   for (i=0; i<height; i++)
  185.   {
  186.     p = src + offset + incr*i;
  187.     for (j=0; j<width; j++)
  188.       putbyte(*p++);
  189.   }
  190.  
  191.   if (optr!=obfr)
  192.     write(outfile,obfr,optr-obfr);
  193.  
  194.   close(outfile);
  195. }
  196.  
  197. /*
  198.  * store as headerless file in U,Y,V,Y format
  199.  */
  200. #ifdef STORM
  201. static void store_sif (char *outname,unsigned char *src[],int offset,int incr,int height)
  202. #else
  203. static void store_sif (outname,src,offset,incr,height)
  204. char *outname;
  205. unsigned char *src[];
  206. int offset, incr, height;
  207. #endif
  208. {
  209.   int i,j;
  210.   unsigned char *py, *pu, *pv;
  211.   static unsigned char *u422, *v422;
  212.  
  213.   if (chroma_format==CHROMA444)
  214.     Error("4:4:4 not supported for SIF format");
  215.  
  216.   if (chroma_format==CHROMA422)
  217.   {
  218.     u422 = src[1];
  219.     v422 = src[2];
  220.   }
  221.   else
  222.   {
  223.     if (!u422)
  224.     {
  225.       if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  226.                                            *Coded_Picture_Height)))
  227.         Error("malloc failed");
  228.       if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  229.                                            *Coded_Picture_Height)))
  230.         Error("malloc failed");
  231.     }
  232.   
  233.     conv420to422(src[1],u422);
  234.     conv420to422(src[2],v422);
  235.   }
  236.  
  237.   strcat(outname,".SIF");
  238.  
  239.   if (!Quiet_Flag)
  240.     fprintf(stderr,"saving %s\n",outname);
  241.  
  242.   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  243.   {
  244.     sprintf(Error_Text,"Couldn't create %s\n",outname);
  245.     Error(Error_Text);
  246.   }
  247.  
  248.   optr = obfr;
  249.  
  250.   for (i=0; i<height; i++)
  251.   {
  252.     py = src[0] + offset + incr*i;
  253.     pu = u422 + (offset>>1) + (incr>>1)*i;
  254.     pv = v422 + (offset>>1) + (incr>>1)*i;
  255.  
  256.     for (j=0; j<horizontal_size; j+=2)
  257.     {
  258.       putbyte(*pu++);
  259.       putbyte(*py++);
  260.       putbyte(*pv++);
  261.       putbyte(*py++);
  262.     }
  263.   }
  264.  
  265.   if (optr!=obfr)
  266.     write(outfile,obfr,optr-obfr);
  267.  
  268.   close(outfile);
  269. }
  270.  
  271. /*
  272.  * store as PPM (PBMPLUS) or uncompressed Truevision TGA ('Targa') file
  273.  */
  274. #ifdef STORM
  275. static void store_ppm_tga(char *outname,unsigned char *src[],int offset,int incr,int height,int tgaflag)
  276. #else
  277. static void store_ppm_tga(outname,src,offset,incr,height,tgaflag)
  278. char *outname;
  279. unsigned char *src[];
  280. int offset, incr, height;
  281. int tgaflag;
  282. #endif
  283. {
  284.   int i, j;
  285.   int y, u, v, r, g, b;
  286.   int crv, cbu, cgu, cgv;
  287.   unsigned char *py, *pu, *pv;
  288.   static unsigned char tga24[14] = {0,0,2,0,0,0,0, 0,0,0,0,0,24,32};
  289.   char header[FILENAME_LENGTH];
  290.   static unsigned char *u422, *v422, *u444, *v444;
  291.  
  292.   if (chroma_format==CHROMA444)
  293.   {
  294.     u444 = src[1];
  295.     v444 = src[2];
  296.   }
  297.   else
  298.   {
  299.     if (!u444)
  300.     {
  301.       if (chroma_format==CHROMA420)
  302.       {
  303.         if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  304.                                              *Coded_Picture_Height)))
  305.           Error("malloc failed");
  306.         if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  307.                                              *Coded_Picture_Height)))
  308.           Error("malloc failed");
  309.       }
  310.  
  311.       if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width
  312.                                            *Coded_Picture_Height)))
  313.         Error("malloc failed");
  314.  
  315.       if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width
  316.                                            *Coded_Picture_Height)))
  317.         Error("malloc failed");
  318.     }
  319.  
  320.     if (chroma_format==CHROMA420)
  321.     {
  322.       conv420to422(src[1],u422);
  323.       conv420to422(src[2],v422);
  324.       conv422to444(u422,u444);
  325.       conv422to444(v422,v444);
  326.     }
  327.     else
  328.     {
  329.       conv422to444(src[1],u444);
  330.       conv422to444(src[2],v444);
  331.     }
  332.   }
  333.  
  334.   strcat(outname,tgaflag ? ".tga" : ".ppm");
  335.  
  336.   if (!Quiet_Flag)
  337.     fprintf(stderr,"saving %s\n",outname);
  338.  
  339.   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  340.   {
  341.     sprintf(Error_Text,"Couldn't create %s\n",outname);
  342.     Error(Error_Text);
  343.   }
  344.  
  345.   optr = obfr;
  346.  
  347.   if (tgaflag)
  348.   {
  349.     /* TGA header */
  350.     for (i=0; i<12; i++)
  351.       putbyte(tga24[i]);
  352.  
  353.     putword(horizontal_size); putword(height);
  354.     putbyte(tga24[12]); putbyte(tga24[13]);
  355.   }
  356.   else
  357.   {
  358.     /* PPM header */
  359.     sprintf(header,"P6\n%d %d\n255\n",horizontal_size,height);
  360.  
  361.     for (i=0; header[i]!=0; i++)
  362.       putbyte(header[i]);
  363.   }
  364.  
  365.   /* matrix coefficients */
  366.   crv = Inverse_Table_6_9[matrix_coefficients][0];
  367.   cbu = Inverse_Table_6_9[matrix_coefficients][1];
  368.   cgu = Inverse_Table_6_9[matrix_coefficients][2];
  369.   cgv = Inverse_Table_6_9[matrix_coefficients][3];
  370.   
  371.   for (i=0; i<height; i++)
  372.   {
  373.     py = src[0] + offset + incr*i;
  374.     pu = u444 + offset + incr*i;
  375.     pv = v444 + offset + incr*i;
  376.  
  377.     for (j=0; j<horizontal_size; j++)
  378.     {
  379.       u = *pu++ - 128;
  380.       v = *pv++ - 128;
  381.       y = 76309 * (*py++ - 16); /* (255/219)*65536 */
  382.       r = Clip[(y + crv*v + 32768)>>16];
  383.       g = Clip[(y - cgu*u - cgv*v + 32768)>>16];
  384.       b = Clip[(y + cbu*u + 32786)>>16];
  385.  
  386.       if (tgaflag)
  387.       {
  388.         putbyte(b); putbyte(g); putbyte(r);
  389.       }
  390.       else
  391.       {
  392.         putbyte(r); putbyte(g); putbyte(b);
  393.       }
  394.     }
  395.   }
  396.  
  397.   if (optr!=obfr)
  398.     write(outfile,obfr,optr-obfr);
  399.  
  400.   close(outfile);
  401. }
  402.  
  403. #ifdef STORM
  404. static void putbyte(int c)
  405. #else
  406. static void putbyte(c)
  407. int c;
  408. #endif
  409. {
  410.   *optr++ = c;
  411.  
  412.   if (optr == obfr+OBFRSIZE)
  413.   {
  414.     write(outfile,obfr,OBFRSIZE);
  415.     optr = obfr;
  416.   }
  417. }
  418.  
  419. #ifdef STORM
  420. static void putword(int w)
  421. #else
  422. static void putword(w)
  423. int w;
  424. #endif
  425. {
  426.   putbyte(w); putbyte(w>>8);
  427. }
  428.  
  429. /* horizontal 1:2 interpolation filter */
  430. #ifdef STORM
  431. static void conv422to444(unsigned char *src,unsigned char *dst)
  432. #else
  433. static void conv422to444(src,dst)
  434. unsigned char *src,*dst;
  435. #endif
  436. {
  437.   int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;
  438.  
  439.   w = Coded_Picture_Width>>1;
  440.  
  441.   if (base.MPEG2_Flag)
  442.   {
  443.     for (j=0; j<Coded_Picture_Height; j++)
  444.     {
  445.       for (i=0; i<w; i++)
  446.       {
  447.         i2 = i<<1;
  448.         im2 = (i<2) ? 0 : i-2;
  449.         im1 = (i<1) ? 0 : i-1;
  450.         ip1 = (i<w-1) ? i+1 : w-1;
  451.         ip2 = (i<w-2) ? i+2 : w-1;
  452.         ip3 = (i<w-3) ? i+3 : w-1;
  453.  
  454.         /* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */
  455.         /* even samples (0 0 256 0 0) */
  456.         dst[i2] = src[i];
  457.  
  458.         /* odd samples (21 -52 159 159 -52 21) */
  459.         dst[i2+1] = Clip[(int)(21*(src[im2]+src[ip3])
  460.                         -52*(src[im1]+src[ip2]) 
  461.                        +159*(src[i]+src[ip1])+128)>>8];
  462.       }
  463.       src+= w;
  464.       dst+= Coded_Picture_Width;
  465.     }
  466.   }
  467.   else
  468.   {
  469.     for (j=0; j<Coded_Picture_Height; j++)
  470.     {
  471.       for (i=0; i<w; i++)
  472.       {
  473.  
  474.         i2 = i<<1;
  475.         im3 = (i<3) ? 0 : i-3;
  476.         im2 = (i<2) ? 0 : i-2;
  477.         im1 = (i<1) ? 0 : i-1;
  478.         ip1 = (i<w-1) ? i+1 : w-1;
  479.         ip2 = (i<w-2) ? i+2 : w-1;
  480.         ip3 = (i<w-3) ? i+3 : w-1;
  481.  
  482.         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
  483.         dst[i2] =   Clip[(int)(  5*src[im3]
  484.                          -21*src[im2]
  485.                          +70*src[im1]
  486.                         +228*src[i]
  487.                          -37*src[ip1]
  488.                          +11*src[ip2]+128)>>8];
  489.  
  490.        dst[i2+1] = Clip[(int)(  5*src[ip3]
  491.                          -21*src[ip2]
  492.                          +70*src[ip1]
  493.                         +228*src[i]
  494.                          -37*src[im1]
  495.                          +11*src[im2]+128)>>8];
  496.       }
  497.       src+= w;
  498.       dst+= Coded_Picture_Width;
  499.     }
  500.   }
  501. }
  502.  
  503. /* vertical 1:2 interpolation filter */
  504. #ifdef STORM
  505. static void conv420to422(unsigned char *src,unsigned char *dst)
  506. #else
  507. static void conv420to422(src,dst)
  508. unsigned char *src,*dst;
  509. #endif
  510. {
  511.   int w, h, i, j, j2;
  512.   int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7;
  513.  
  514.   w = Coded_Picture_Width>>1;
  515.   h = Coded_Picture_Height>>1;
  516.  
  517.   if (progressive_frame)
  518.   {
  519.     /* intra frame */
  520.     for (i=0; i<w; i++)
  521.     {
  522.       for (j=0; j<h; j++)
  523.       {
  524.         j2 = j<<1;
  525.         jm3 = (j<3) ? 0 : j-3;
  526.         jm2 = (j<2) ? 0 : j-2;
  527.         jm1 = (j<1) ? 0 : j-1;
  528.         jp1 = (j<h-1) ? j+1 : h-1;
  529.         jp2 = (j<h-2) ? j+2 : h-1;
  530.         jp3 = (j<h-3) ? j+3 : h-1;
  531.  
  532.         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
  533.         /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */
  534.         dst[w*j2] =     Clip[(int)(  3*src[w*jm3]
  535.                              -16*src[w*jm2]
  536.                              +67*src[w*jm1]
  537.                             +227*src[w*j]
  538.                              -32*src[w*jp1]
  539.                              +7*src[w*jp2]+128)>>8];
  540.  
  541.         dst[w*(j2+1)] = Clip[(int)(  3*src[w*jp3]
  542.                              -16*src[w*jp2]
  543.                              +67*src[w*jp1]
  544.                             +227*src[w*j]
  545.                              -32*src[w*jm1]
  546.                              +7*src[w*jm2]+128)>>8];
  547.       }
  548.       src++;
  549.       dst++;
  550.     }
  551.   }
  552.   else
  553.   {
  554.     /* intra field */
  555.     for (i=0; i<w; i++)
  556.     {
  557.       for (j=0; j<h; j+=2)
  558.       {
  559.         j2 = j<<1;
  560.  
  561.         /* top field */
  562.         jm6 = (j<6) ? 0 : j-6;
  563.         jm4 = (j<4) ? 0 : j-4;
  564.         jm2 = (j<2) ? 0 : j-2;
  565.         jp2 = (j<h-2) ? j+2 : h-2;
  566.         jp4 = (j<h-4) ? j+4 : h-2;
  567.         jp6 = (j<h-6) ? j+6 : h-2;
  568.  
  569.         /* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */
  570.         /* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */
  571.         dst[w*j2] = Clip[(int)(  1*src[w*jm6]
  572.                          -7*src[w*jm4]
  573.                          +30*src[w*jm2]
  574.                         +248*src[w*j]
  575.                          -21*src[w*jp2]
  576.                           +5*src[w*jp4]+128)>>8];
  577.  
  578.         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
  579.         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
  580.         dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4]
  581.                              -35*src[w*jm2]
  582.                             +194*src[w*j]
  583.                             +110*src[w*jp2]
  584.                              -24*src[w*jp4]
  585.                               +4*src[w*jp6]+128)>>8];
  586.  
  587.         /* bottom field */
  588.         jm5 = (j<5) ? 1 : j-5;
  589.         jm3 = (j<3) ? 1 : j-3;
  590.         jm1 = (j<1) ? 1 : j-1;
  591.         jp1 = (j<h-1) ? j+1 : h-1;
  592.         jp3 = (j<h-3) ? j+3 : h-1;
  593.         jp5 = (j<h-5) ? j+5 : h-1;
  594.         jp7 = (j<h-7) ? j+7 : h-1;
  595.  
  596.         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
  597.         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
  598.         dst[w*(j2+1)] = Clip[(int)( 7*src[w*jp5]
  599.                              -35*src[w*jp3]
  600.                             +194*src[w*jp1]
  601.                             +110*src[w*jm1]
  602.                              -24*src[w*jm3]
  603.                               +4*src[w*jm5]+128)>>8];
  604.  
  605.         dst[w*(j2+3)] = Clip[(int)(  1*src[w*jp7]
  606.                              -7*src[w*jp5]
  607.                              +30*src[w*jp3]
  608.                             +248*src[w*jp1]
  609.                              -21*src[w*jm1]
  610.                               +5*src[w*jm3]+128)>>8];
  611.       }
  612.       src++;
  613.       dst++;
  614.     }
  615.   }
  616. }
  617.